// Created: Dec 11, 2014
//
// Author: wjinwen.1988@gmail.com

#include "chi/func.h"

#include <sys/resource.h>

namespace chi {

int Func::CheckPid(const char* lock_file) {
  char buffer[64], *p;
  int otherpid = 0, lfp;
  lfp = open(lock_file, O_RDONLY, 0);
  if (lfp > 0) {
    read(lfp, buffer, 64);
    close(lfp);
    buffer[63] = '\0';
    p = strchr(buffer, '\n');
    if (p) 
      *p = '\0';
    otherpid = atoi(buffer);
  }
  if (otherpid > 0) {
    if (kill(otherpid, 0) != 0) {
      otherpid = 0;
    }
  }
  return otherpid;
}  // end CheckPid

void Func::WritePid(const char* lock_file) {
  int lfp = open(lock_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
  if (lfp < 0)
    exit(1);
  if (lockf(lfp, F_TLOCK, 0) < 0) {
    fprintf(stderr, "already run.\n");
    exit(0);
  }

  char str[32];
  sprintf(str, "%d\n", getpid());
  ssize_t len = strlen(str);
  ssize_t ret = write(lfp, str, strlen(str));
  if (ret != len) {
    fprintf(stderr, "can't write pid file: %s\n", lock_file);
    exit(0);
  }
  close(lfp);
} // end WritPid

int Func::StartDaemon(const char* pid_file) {
  if (getpid() == 1)
    return 0;

  int pid = fork();
  if (pid < 0) exit(1);
  if (pid > 0) return pid;

  WritePid(pid_file);

  int fd = open("/dev/null", 0);
  if (fd != -1) {
    dup2(fd, 0);
    close(fd);
  }
  
  return pid;
}

}  // namespace chi

